﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ESpilWebservicePrototype.ViewModels;

namespace ESpilWebservicePrototype
{
    public class UserService
    {
        private ESpilDataContext DataContext;
        public UserService()
        {
            DataContext = new ESpilDataContext();
        }

        /// <summary>
        /// Validates user
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password">Clear password</param>
        /// <returns></returns>
        internal int ValidateUser(string username, string hashedpassword)
        {
            User user = DataContext.Users.FirstOrDefault(p => p.Username == username && p.Password == hashedpassword);
            if (user!=null)
            {
                user.LastLogin = DateTime.Now;
                DataContext.SubmitChanges();
                return user.UserID;
            }

            return -1;
        }

        internal bool CreateUser(string username, string hashedpassword, string name, string lastName, string cLass)
        {
            User user = new User();
            user.Username = username;
            user.Password = hashedpassword;
            user.LastLogin = DateTime.Now;
            user.Name = name;
            user.Lastname = lastName;
            user.Class = cLass;

            DataContext.Users.InsertOnSubmit(user);
            DataContext.SubmitChanges();

            return user.UserID > 0;
        }

        internal bool CreateHighscore(int userID, int score)
        {
            User user = DataContext.Users.FirstOrDefault(p=>p.UserID == userID);
            if (user == null)
                return false;

            Highscore highscore = new Highscore();
            highscore.User = user;
            highscore.Score = score;
            highscore.Created = DateTime.Now;

            DataContext.Highscores.InsertOnSubmit(highscore);
            DataContext.SubmitChanges();

            return highscore.HighscoreID > 0;
        }

        internal List<Highscore> GetTopHighscores(int count)
        {
            List<Highscore> highscores = DataContext.Highscores.OrderByDescending(p => p.Score).Take(count).ToList<Highscore>();
            return highscores;
        }

        public User GetUser(int userID)
        {
            User user = DataContext.Users.FirstOrDefault(p => p.UserID == userID);
            return user;
        }

        public bool EditUser(int userID, string username, string password, string name, string lastName, string cLass)
        {
            User user = DataContext.Users.FirstOrDefault(p => p.UserID == userID);
            user.Username = username;
            user.Password = password;
            user.Name = name;
            user.Lastname = lastName;
            user.Class = cLass;

            DataContext.SubmitChanges();
            return true;
        }

        public Boolean IsFriend(int userID, int friendID)
        {
            //nice one riis :P
             return DataContext.Friends.Any(p => p.UserID == userID && p.FriendID == friendID || p.UserID == friendID && p.FriendID == userID);
        }

        public void BefriendUser(int userID, int friendID)
        {
            if (DataContext.Friends.Any(p => p.UserID == userID && p.FriendID == friendID || p.UserID == friendID && p.FriendID == userID))
                return;

            Friends friend = new Friends();
            friend.UserID = userID;
            friend.FriendID = friendID;
            friend.Confirmed = false;

            DataContext.Friends.InsertOnSubmit(friend);
            DataContext.SubmitChanges();
        }

        //Accept a friend invite
        public void AcceptFriendInvite(int userID, int friendID)
        {
            Friends friend = DataContext.Friends.FirstOrDefault(p => p.UserID == userID && p.FriendID == friendID);
            friend.Confirmed = true;
            DataContext.SubmitChanges();
        }

        //Cancel a friend invite
        public void CancelFriendInvite(int userID, int friendID)
        {
            Friends friend = DataContext.Friends.FirstOrDefault(p => p.UserID == userID && p.FriendID == friendID);
            DataContext.Friends.DeleteOnSubmit(friend);
            DataContext.SubmitChanges();
        }

        //Return users, where confirmed is set to false
        public List<FriendsViewModel> GetPendingInvites(int userID)
        {
            var pendingInvited = DataContext.Friends.Where(p => !p.Confirmed && p.FriendID == userID);
            List<FriendsViewModel> models = new List<FriendsViewModel>();
            foreach (var friends in pendingInvited)
            {
                models.Add(FriendsViewModel.FromModel(friends));
            }

            return models;
        }

        internal List<User> GetAllFriends(int userID)
        {
            var friends = DataContext.Friends.Where(p => (p.UserID == userID || p.FriendID == userID)).Where(p=>p.Confirmed);

            List<User> trueFriends = new List<User>();

            foreach (Friends connection in friends)
            {
                if (connection.FriendID == userID)
                {
                    trueFriends.Add(DataContext.Users.FirstOrDefault(p => p.UserID == connection.UserID));
                }
                else
                {
                    trueFriends.Add(DataContext.Users.FirstOrDefault(p => p.UserID == connection.FriendID));
                }
            }

            return trueFriends;
        }

        internal List<UserListItemViewModel> GetAllUsers(string query, int userID)
        {
            if (String.IsNullOrWhiteSpace(query))
            {
                return new List<UserListItemViewModel>();
            }

            var ppl = from p in DataContext.Users
                      where p.Name.Contains(query)
                      where p.UserID != userID
                      select new UserListItemViewModel() 
                      {
                            Lastname = p.Lastname,
                            Name = p.Name,
                            UserID = p.UserID,
                            Username = p.Username
                      };

            return ppl.ToList();
        }
    }
}